package com.infinitus.nginxInfo.service.util;


import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Symmetric
{
  private String keyalg;
  private String algorithm;
  private String mode;
  private String padding;
  private int keysize;
  private String provider;
  protected static Log LOG = LogFactory.getLog(Symmetric.class);

  public Symmetric(String keyalg, String algorithm, int keysize) {
    this(keyalg, algorithm, "", "", keysize);
  }

  public Symmetric(String keyalg, String algorithm, String mode, String padding, int keysize)
  {
    this.provider = "SUN";

    this.keyalg = keyalg;
    this.algorithm = algorithm;
    this.mode = mode;
    this.padding = padding;
    this.keysize = keysize;
    Security.addProvider(new BouncyCastleProvider());
    this.provider = "BC";
  }

  public Key generateKey()
    throws Exception
  {
    try
    {
      KeyGenerator kg = KeyGenerator.getInstance(this.keyalg, this.provider);
      kg.init(this.keysize, new SecureRandom());

      Key key = kg.generateKey();
      LOG.debug(Integer.toString(key.getEncoded().length * 8));
      return key;
    } catch (Exception e) {
      throw new Exception("没有这种加密算法");
    }
  }

  public byte[] encrypt(byte[] plaintext, Key key)
    throws Exception
  {
    try
    {
      Cipher cipher = Cipher.getInstance(formatAlgorithm(), this.provider);

      cipher.init(1, key);

      byte[] cryptotext = cipher.doFinal(plaintext);
      return cryptotext;
    } catch (InvalidKeyException e) {
      throw new Exception("密钥非法");
    } catch (NoSuchAlgorithmException e) {
      throw new Exception("没有这种加密算法");
    } catch (BadPaddingException e) {
      throw new Exception("加密失败");
    }
  }

  public byte[] decrypt(byte[] cryptotext, Key key)
    throws Exception
  {
    try
    {
      Cipher cipher = Cipher.getInstance(formatAlgorithm(), this.provider);

      cipher.init(2, key);

      byte[] plaintext = cipher.doFinal(cryptotext);
      return plaintext;
    } catch (InvalidKeyException e) {
      throw new Exception("密钥非法");
    } catch (NoSuchAlgorithmException e) {
      throw new Exception("没有这种解密算法");
    } catch (BadPaddingException e) {
      throw new Exception("解密失败");
    }
  }

  public String encrypt(String plaintext, Key key)
    throws Exception
  {
    byte[] cryptotext = encrypt(plaintext.getBytes("UTF-8"), key);
    return Base64.encode(cryptotext);
  }

  public String decrypt(String cryptotext, Key key)
    throws Exception
  {
    byte[] plaintext = decrypt(Base64.decode(cryptotext), key);
    return new String(plaintext, "UTF-8");
  }

  private String formatAlgorithm()
  {
    String str = this.algorithm;
    if ((null != this.mode) && (!("".equals(this.mode)))) {
      str = str + "/" + this.mode;
    }
    if ((null != this.padding) && (!("".equals(this.padding)))) {
      str = str + "/" + this.padding;
    }
    return str;
  }

  public String getProvider() {
    return this.provider;
  }
}